package soccerscope.dialog;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.ListSelectionModel;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import soccerscope.model.ClientScene;
import soccerscope.model.PlayMode;
import soccerscope.model.SoccerObject;
import soccerscope.model.WorldModel;
import soccerscope.training.TrainingModel;
import soccerscope.view.SoccerObjectSelectObserver;

/**
 * This code was generated using CloudGarden's Jigloo SWT/Swing GUI Builder,
 * which is free for non-commercial use. If Jigloo is being used commercially
 * (ie, by a corporation, company or business for any purpose whatever) then you
 * should purchase a license for each developer using Jigloo. Please visit
 * www.cloudgarden.com for details. Use of Jigloo implies acceptance of these
 * licensing terms. ************************************* A COMMERCIAL LICENSE
 * HAS NOT BEEN PURCHASED for this machine, so Jigloo or this code cannot be
 * used legally for any corporate or commercial purpose.
 * *************************************
 */
public class TrainingSetupDialog
    extends JDialog
    implements ActionListener, ListSelectionListener,
    SoccerObjectSelectObserver {

  private static final long   serialVersionUID = 6167667904233838593L;

  private JTabbedPane         mainTabs;

  private JPanel              execPanel;

  private JButton             saveScenario;

  private JPanel              selectObjectPanel;

  private ObjectTrainingPanel objectTrainingDialog;

  private GameConditionPanel  gameConditionPanel;

  private JLabel              selDescr;

  private JComboBox           selectObjectBox;

  private JButton             loadScenario;

  private JPanel              buttonPanel;

  private JPanel              statisticPanel;

  private JPanel              setupPanel;

  private ClientScene         scene            = null;

  private TrainingModel       tm;

  private SoccerObject[]      objects          = new SoccerObject[23];

  private JList               playModeList;

  /**
   * The constructor creates a reference to the scene and to the main-frame,
   * because it is a modal dialog. From the scene, all player/ball data,
   * including the TrainingModels are refered to.
   * 
   * @param frame -
   *          the soccerscope frame
   * @param scene -
   *          the actual scene
   */
  public TrainingSetupDialog(
      JFrame frame,
      ClientScene scene) {

    super(frame);
    // this.scene = scene;
    //
    // if (WorldModel.getInstance().trainModel == null) {
    // WorldModel.getInstance().trainModel =
    // new TrainingModel(scene);
    // }
    // tm = WorldModel.getInstance().trainModel;
    //		
    // // set the players and the ball to the array
    // for (int i = 0; i < 22; i++) {
    // objects[i] = this.scene.player[i];
    // }
    // objects[22] = this.scene.ball;
    this.setScene(scene);

    this.initGUI();
    this.pack();
  }

  /**
   * This method sets the scene of soccerscope
   * 
   * @param scene -
   *          the actual scene
   */
  public void setScene(ClientScene scene) {

    this.scene = scene;
    boolean newInst = false;
    if (WorldModel.getInstance().trainModel == null) {
      WorldModel.getInstance().trainModel = new TrainingModel(scene);
      newInst = true;
    }
    this.tm = WorldModel.getInstance().trainModel;

    // set the players and the ball to the array
    for (int i = 0; i < 22; i++) {
      this.objects[i] = this.scene.player[i];
    }
    this.objects[22] = this.scene.ball;

    // refresh GUI vision
    if (!newInst) {
      if (this.objectTrainingDialog != null) {
        this.objectTrainingDialog.setObject(this.objects[0],
            this.tm.objectTrainingModel[0]);
        this.selectObjectBox.setSelectedIndex(0);
      }
    }
  }

  private void initGUI() {

    try {
      {
        BorderLayout thisLayout = new BorderLayout();
        this.getContentPane().setLayout(thisLayout);
        this.setResizable(false);
        this.setTitle("Dainamite Training-Scenario Editor");
        {
          this.mainTabs = new JTabbedPane();
          this.getContentPane().add(this.mainTabs, BorderLayout.CENTER);
          {
            this.setupPanel = new JPanel();
            GridBagLayout setupPanelLayout = new GridBagLayout();
            setupPanelLayout.columnWeights = new double[] { 0.1, 0.1 };
            setupPanelLayout.columnWidths = new int[] { 7, 7 };
            setupPanelLayout.rowWeights = new double[] { 0.1, 0.1 };
            setupPanelLayout.rowHeights = new int[] { 7, 7 };
            this.setupPanel.setLayout(setupPanelLayout);
            this.mainTabs.addTab("Training-Setup", null, this.setupPanel, null);
            {
              this.selectObjectPanel = new JPanel();
              GridBagLayout selectObjectPanelLayout = new GridBagLayout();
              selectObjectPanelLayout.columnWeights = new double[] { 0.1, 0.1 };
              selectObjectPanelLayout.columnWidths = new int[] { 7, 7 };
              selectObjectPanelLayout.rowWeights = new double[] { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 };
              selectObjectPanelLayout.rowHeights = new int[] { 7, 7, 7, 7, 7, 7, 7 };
              this.selectObjectPanel.setLayout(selectObjectPanelLayout);
              this.setupPanel.add(this.selectObjectPanel,
                  new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
                      GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                      new Insets(0, 0, 0, 0), 0, 0));
              {
                this.selDescr = new JLabel();
                this.selectObjectPanel.add(this.selDescr,
                    new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
                        GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                        new Insets(3, 3, 3, 3), 0, 0));
                this.selDescr.setText("Select Object:");
              }
              {
                ComboBoxModel selectObjectBoxModel = new DefaultComboBoxModel(
                    new String[] { "Player 1 [Left]", "Player 2 [Left]", "Player 3 [Left]", "Player 4 [Left]", "Player 5 [Left]", "Player 6 [Left]", "Player 7 [Left]", "Player 8 [Left]", "Player 9 [Left]", "Player 10 [Left]", "Player 11 [Left]",

                    "Player 1 [Right]", "Player 2 [Right]", "Player 3 [Right]", "Player 4 [Right]", "Player 5 [Right]", "Player 6 [Right]", "Player 7 [Right]", "Player 8 [Right]", "Player 9 [Right]", "Player 10 [Right]", "Player 11 [Right]",

                    "Ball" });
                this.selectObjectBox = new JComboBox();
                this.selectObjectPanel.add(this.selectObjectBox,
                    new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
                        GridBagConstraints.CENTER, GridBagConstraints.NONE,
                        new Insets(3, 3, 3, 3), 0, 0));
                this.selectObjectBox.setModel(selectObjectBoxModel);
                this.selectObjectBox.setName("Select Object");
                this.selectObjectBox.addActionListener(this);
              }
              {
                // List With PlayModes:
                JLabel selPlayMode = new JLabel("Select Start-PlayMode:");
                this.selectObjectPanel.add(selPlayMode, new GridBagConstraints(
                    0, 1, 2, 1, 0.0, 0.0, GridBagConstraints.SOUTHWEST,
                    GridBagConstraints.NONE, new Insets(3, 3, 3, 3), 0, 0));

                DefaultListModel playModeListModel = new DefaultListModel();
                for (PlayMode.PLAY_MODE p : PlayMode.allPlayModes) {
                  playModeListModel.addElement(p);
                }

                this.playModeList = new JList();
                this.playModeList.setBorder(new EtchedBorder());
                this.playModeList
                    .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
                this.playModeList.setVisibleRowCount(10);
                this.playModeList.setModel(playModeListModel);
                JScrollPane scrollingList = new JScrollPane(this.playModeList);
                this.selectObjectPanel.add(scrollingList,
                    new GridBagConstraints(0, 2, 2, 2, 0.0, 0.0,
                        GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
                        new Insets(3, 3, 3, 3), 0, 0));
                this.playModeList.addListSelectionListener(this);
                this.playModeList.setSelectedValue(this.tm.startPlayMode, true);
              }
            }
            {
              this.objectTrainingDialog = new ObjectTrainingPanel();
              this.objectTrainingDialog.setObject(this.objects[0],
                  this.tm.objectTrainingModel[0]);
              this.setupPanel.add(this.objectTrainingDialog,
                  new GridBagConstraints(1, 0, 1, 2, 0.0, 0.0,
                      GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                      new Insets(0, 0, 0, 0), 0, 0));
            }
          }
          {
            this.gameConditionPanel = new GameConditionPanel(this.scene);
            this.mainTabs.addTab("Training-State", null,
                this.gameConditionPanel, null);
          }
          {
            this.statisticPanel = new JPanel();
            this.mainTabs.addTab("Training-Statistics", null,
                this.statisticPanel, null);
          }
          {
            this.execPanel = new JPanel();
            this.mainTabs.addTab("Training-Execution", null, this.execPanel,
                null);
          }
        }
        {
          this.buttonPanel = new JPanel();
          this.getContentPane().add(this.buttonPanel, BorderLayout.SOUTH);
          {
            this.loadScenario = new JButton();
            this.buttonPanel.add(this.loadScenario);
            this.loadScenario.setText("Load");
            this.loadScenario.addActionListener(this);
          }
          {
            this.saveScenario = new JButton();
            this.buttonPanel.add(this.saveScenario);
            this.saveScenario.setText("Save");
            this.saveScenario.addActionListener(this);
          }
        }
      }
      this.setSize(600, 500);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * This method listens for changes in the Combo-Box - which will update the
   * object- training-dialog by setting a new object (ball or player).
   * 
   * @param arg0 -
   *          the event
   */
  public void actionPerformed(ActionEvent arg0) {

    if (arg0.getSource() == this.selectObjectBox) {
      int index = this.selectObjectBox.getSelectedIndex();
      if (index >= 0) {
        this.objectTrainingDialog.setObject(this.objects[index],
            this.tm.objectTrainingModel[index]);
      }
      this.objectTrainingDialog.repaint();
    }
    else if (arg0.getSource() == this.saveScenario) {
      JFileChooser chooser = new JFileChooser();

      int returnVal = chooser.showOpenDialog(this.getParent());
      if (returnVal == JFileChooser.APPROVE_OPTION) {
        String filename = chooser.getSelectedFile().getAbsolutePath();
        boolean b = TrainingModel.saveTrainingModel(this.tm, filename);
        if (!b) {
          JOptionPane.showMessageDialog(this,
              "Error Saving the file: " + filename, "ERROR",
              JOptionPane.ERROR_MESSAGE);

        }
      }
    }
    else if (arg0.getSource() == this.loadScenario) {
      JFileChooser chooser = new JFileChooser();

      int returnVal = chooser.showOpenDialog(this.getParent());
      if (returnVal == JFileChooser.APPROVE_OPTION) {
        String filename = chooser.getSelectedFile().getAbsolutePath();
        TrainingModel tm = TrainingModel.loadTrainingModel(filename);
        if (tm != null) {
          WorldModel.getInstance().trainModel = tm;
          this.tm = tm;
          ClientScene cscene = ClientScene.createScene(tm);
          // this.scene = cscene;
          WorldModel.getSceneSet().addTrainingScene(cscene);
          this.setVisible(false);
        }
      }
    }
  }

  /**
   * This method changes the start-playmode of the training-scenario, chosen
   * from the list <playModeList>!
   */
  public void valueChanged(ListSelectionEvent arg0) {

    if (arg0.getSource() == this.playModeList && this.playModeList
        .getSelectedIndex() >= 0) {
      this.tm.startPlayMode = (PlayMode.PLAY_MODE) this.playModeList
          .getSelectedValue();
    }
  }

  /**
   * This method checks, if a soccer-object was selected on the screen. If so,
   * it it notified here, and the UI is updated consequently.
   * 
   * @param id -
   *          the ID - corresponds to the entries in the combo-box
   * @param flat
   *          true, if selected, false if deselected
   */
  public void selectSoccerObject(int id,
      boolean flat) {

    if (!this.isVisible()) {
      return;
    }
    if (flat) {
      this.objectTrainingDialog.setObject(this.objects[id],
          this.tm.objectTrainingModel[id]);
      this.selectObjectBox.setSelectedIndex(id);
    }
  }

  @Override
  public void setVisible(boolean flag) {

    super.setVisible(flag);

    this.playModeList.setSelectedValue(this.tm.startPlayMode, true);
  }

}
